package com.vcredit.creditcat.service.product;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.vcredit.creditcat.dto.product.crf.CRFAuthenticationDto;
import com.vcredit.creditcat.dto.product.crf.CRFCallRecordDto;
import com.vcredit.creditcat.dto.product.crf.CRFDeviceInfoDto;
import com.vcredit.creditcat.dto.product.crf.CRFGeoDto;
import com.vcredit.creditcat.dto.product.crf.CRFLiveness;
import com.vcredit.creditcat.dto.product.crf.CRFOrderInfoDto;
import com.vcredit.creditcat.dto.product.crf.CRFPhoneBookDto;
import com.vcredit.creditcat.dto.product.crf.CRFSocialRelationDto;
import com.vcredit.creditcat.dto.product.crf.CRFUserInfoDto;
import com.vcredit.creditcat.dto.product.crf.CRFVocationDto;
import com.vcredit.creditcat.enumtype.AuthItemEnum;
import com.vcredit.creditcat.enumtype.MerchantProductEnum;
import com.vcredit.creditcat.exception.ProductCanNotApplyException;
import com.vcredit.creditcat.exception.ResourceException;
import com.vcredit.creditcat.model.AddressList;
import com.vcredit.creditcat.model.AuthIdentity;
import com.vcredit.creditcat.model.AuthPersonalAddress;
import com.vcredit.creditcat.model.CallLog;
import com.vcredit.creditcat.model.Cust;
import com.vcredit.creditcat.model.CustAccount;
import com.vcredit.creditcat.model.CustProductApply;
import com.vcredit.creditcat.model.ProductItem;
import com.vcredit.creditcat.model.Relative;
import com.vcredit.creditcat.service.AddressListService;
import com.vcredit.creditcat.service.AuthPersonalAddressService;
import com.vcredit.creditcat.service.CallLogService;
import com.vcredit.creditcat.service.CustAccountService;
import com.vcredit.creditcat.service.CustProductApplyService;
import com.vcredit.creditcat.service.product.enumtype.ProductEnumType;
import com.vcredit.creditcat.util.ConcurrentDateUtil;
import com.vcredit.creditcat.util.Utility;

/**
 * Created by liaoshengjun on 2017/8/3.
 */
@Service("creditCRF")
public class CreditCRFApplyService implements IProductApplyService {
	@Autowired
	@Qualifier("productStrategyContext")
	private ICreditCommonService creditCommonApplyService;
	
	@Autowired
	private CustProductApplyService custProductApplyService;
	
	@Autowired
	private AddressListService addressListService;
	
	@Autowired
	private AuthPersonalAddressService authPersonalAddressService;

	@Autowired
	private CallLogService callLogService;

	@Autowired
	private CustAccountService custAccountService;

	@Value("${crf.return.url}")
	private String returnUrl;

	@Value("${resource.image.url}")
	private String imagUrl;

	@Value("${crf.app.channel}")
	private String appChannel;

	@Value("${crf.salesman.no}")
	private String salesmanNo;

	@Value("${crf.agent.no}")
	private String agentNo;


	@Override
	public Object applyCommit(Long custId, Long productId,Map<String,String> otherParams) throws Exception {
		Object prepareProductApplyParamDto = creditCommonApplyService.prepareProductApplyUserInfo(custId, productId,
				MerchantProductEnum.creditCRF,otherParams);
		if (null == prepareProductApplyParamDto) {
			creditCommonApplyService.saveCustProductApply(this.getSaveAuditResultParam(custId, productId, null));
			return null;
		}else if (prepareProductApplyParamDto instanceof Map) {
			Map<String, Object> resultMap = (Map<String, Object>) prepareProductApplyParamDto;
			if (resultMap.containsKey("expiredList")) {
				//返回给前端 过期的信用项
				return resultMap.get("expiredList");
			}
				creditCommonApplyService.saveCustProductApply(
						this.getSaveAuditResultParam(custId, productId, resultMap));
				return null;
		}
		return null;
	}

	@Override
	public void queryLimit(CustProductApply custProductApply) throws Exception {

	}

	@Override
	public Boolean hasAlreadyAuditAmount(Object object)
			throws ProductCanNotApplyException,IOException {
		return null;
	}

	@Override
	public Object getProductCommitParam(Long productId, Cust cust, Map<AuthItemEnum, Object> itemMap,Map<String,String> otherParams)
			throws ResourceException, Exception {
		CRFOrderInfoDto order = new CRFOrderInfoDto();
		order.setOrderId("XYM_"+cust.getCustId());
		AuthIdentity authIdentity = (AuthIdentity) itemMap.get(AuthItemEnum.IDENTITY_REAL);
		List<Relative> relativeList = (List<Relative>) itemMap.get(AuthItemEnum.CONTACTS);
		CustAccount account=new CustAccount();
		account.setCustId(cust.getCustId());
		List<CustAccount> accountList=custAccountService.find(account);
		CustAccount custAccount=accountList.get(0);
		// 请求信息
		CRFUserInfoDto userInfo = new CRFUserInfoDto();
		userInfo.setAppChannel(appChannel);
		userInfo.setAgentNo(agentNo);
		userInfo.setSalesmanNo(salesmanNo);
		userInfo.setPhone(custAccount.getUserName());
		order.setUserInfo(userInfo);
		// 身份信息
		CRFAuthenticationDto authenticationDto = new CRFAuthenticationDto();
		authenticationDto.setApplyIdNo(cust.getCustIdno());
		authenticationDto.setApplyName(cust.getCustName());
		authenticationDto.setIdCardImg(imagUrl+"/"+authIdentity.getIdFront());
		authenticationDto.setIdCardImgBack(imagUrl+"/"+authIdentity.getIdBack());
		order.setAuthentication(authenticationDto);
		// 用户照片信息
		CRFLiveness liveness=new CRFLiveness();
		liveness.setLivenessBlink(imagUrl+"/"+authIdentity.getIdHandheld());
		order.setLiveness(liveness);
		// 联系人信息
		CRFSocialRelationDto relationDto = new CRFSocialRelationDto();
		for (Relative relative : relativeList) {
			if (relationDto.getFavoriteName() == null && relative.getRelationType().equals(2)) {
				relationDto.setFavoriteName(relative.getRelationName());
				relationDto.setFavoriteTel(relative.getRelationMobile());
				String relationship =
						creditCommonApplyService.getProductEnumCode(productId, ProductEnumType.relationship.getCode(),
								relative.getRelation());
				relationDto.setFavoriteRelation(relationship);
				continue;
			}
			if (relationDto.getEmergencyName() == null && relative.getRelationType().equals(1)) {
				relationDto.setEmergencyName(relative.getRelationName());
				relationDto.setEmergencyTel(relative.getRelationMobile());
				String relationship =
						creditCommonApplyService.getProductEnumCode(productId, ProductEnumType.relationship.getCode(),
								relative.getRelation());
				relationDto.setEmergencyRelation(relationship);
			}
		}
		order.setSocialRelation(relationDto);

		// 通讯录
		List<AddressList> addressLists = addressListService.findByCustId(cust.getCustId());
		List<CRFPhoneBookDto> crfPhoneBookDtoList=new ArrayList<>();
		Set<String> set = new HashSet<>();
		for (AddressList addressList : addressLists) {
			set.add(addressList.getName());
		}
		for (String name : set) {
			CRFPhoneBookDto crfPhoneBookDto = new CRFPhoneBookDto();
			crfPhoneBookDto.setName(name);
			List<String> phoneList = new ArrayList<>();
			for (AddressList addressList : addressLists) {
				if (addressList.getName().equals(name)) {
					phoneList.add(addressList.getMobile());
				}
			}
			crfPhoneBookDto.setPhone(phoneList);
			crfPhoneBookDtoList.add(crfPhoneBookDto);
		}
		order.setPhoneBook(crfPhoneBookDtoList);
		// 通话记录
		List<CallLog> callLogs=callLogService.findByCustId(cust.getCustId());
		if(callLogs.size()>0){
			List<CRFCallRecordDto> list=new ArrayList<>();
			for (CallLog callLog:callLogs){
				CRFCallRecordDto crfCallRecordDto=new CRFCallRecordDto();
				crfCallRecordDto.setPhone(callLog.getCallerNum());
				crfCallRecordDto.setTime(callLog.getCallTime());
				crfCallRecordDto.setDuration(callLog.getTalkTime());
				crfCallRecordDto.setType(String.valueOf(callLog.getCallType()));
				list.add(crfCallRecordDto);
			}
			order.setCallRecord(list);
		}
		// 职业信息
		CRFVocationDto crfVocationDto=new CRFVocationDto();
		List<AuthPersonalAddress> addressList=authPersonalAddressService.findByCustId(cust.getCustId(),0);
		if (addressList.size()>0){
			AuthPersonalAddress address=addressList.get(0);
			crfVocationDto.setType("2");
			crfVocationDto.setWorkName(address.getAddressName());
			crfVocationDto.setWorkTel(address.getPhone());
			crfVocationDto.setAddress(address.getAddress());
			crfVocationDto.setProvince(address.getProvince());
			crfVocationDto.setCity(address.getCity());
			crfVocationDto.setZone(address.getZone());
			//crfVocationDto.setRoad(address.getRoad());
			crfVocationDto.setProvinceCode(address.getProvinceCode());
			crfVocationDto.setCityCode(address.getCityCode());
			crfVocationDto.setZoneCode(address.getZoneCode());
			crfVocationDto.setIp(address.getIp());
			CRFGeoDto crfGeoDto=new CRFGeoDto();
			crfGeoDto.setAddress(address.getGeoAddress());
			crfGeoDto.setLatitude(address.getGeoLatitude());
			crfGeoDto.setLongitude(address.getGeoLongitude());
			crfGeoDto.setCity(address.getGeoCity());
			crfGeoDto.setDistinct(address.getGeoZone());
			crfGeoDto.setRoad(address.getGeoRoad());
			crfVocationDto.setGeo(crfGeoDto);
		}
		order.setVocation(crfVocationDto);
		// 设备信息
		CRFDeviceInfoDto crfDeviceInfoDto=new CRFDeviceInfoDto();
		crfDeviceInfoDto.setPhone(custAccount.getUserName());
		crfDeviceInfoDto.setImei(otherParams.get("deviceNo"));
		crfDeviceInfoDto.setMobileDevice(otherParams.get("phoneModel"));
		crfDeviceInfoDto.setOsType(otherParams.get("operatingSys").toLowerCase().matches("android.*")?"android":"ios");
		order.setDeviceInfo(crfDeviceInfoDto);
		//回调 url
		order.setReturnUrl(returnUrl);
		return order;
	}

	@Override
	public Object getCreditAmountParam(Cust cust, ProductItem productItem) throws Exception {
		return null;
	}

	@Override
	public Object getAudInputParam(Object dto) throws ProductCanNotApplyException {
		return null;
	}

	@Override
	public CustProductApply getSaveAuditResultParam(Long custId, Long productId, Object input) throws Exception {
		CustProductApply custProductApply = new CustProductApply();

		CustProductApply custProductApplySelect = custProductApplyService.findNewApplyProduct(productId, custId);
		boolean isNull = null == custProductApplySelect;
		String flowNo = isNull ? Utility.nextCode(MerchantProductEnum.creditCRF.name().toUpperCase())
				: custProductApplySelect.getFlowNo();
		custProductApply.setFlowNo(flowNo);
		custProductApply.setCustId(custId);
		custProductApply.setProductId(productId);
		if (!isNull) {
			custProductApply.setApplyId(custProductApplySelect.getApplyId());
		}
		custProductApply.setIsApply(true);
		custProductApply.setAuditTime(ConcurrentDateUtil.formatDateTime(new Date()));
		custProductApply.setCreditApplyTime(ConcurrentDateUtil.formatDateTime(ConcurrentDateUtil.addDayTime(new Date(), 30)));
		if (null == input) {
			custProductApply.setRejectMsg("撞库");
			custProductApply.setSuggestion("");
			custProductApply.setCreditAmt(0);
			custProductApply.setCreditExpiretime("");
			custProductApply.setAuditResult(5);
			return custProductApply;
		}
		Map<String,String> map=(Map<String,String>)input;
		if("00".equals(map.get("status"))){
			custProductApply.setCreditAmt(0);
			custProductApply.setRejectMsg("");
			custProductApply.setSuggestion("");
			custProductApply.setCreditExpiretime("");
			custProductApply.setAuditResult(2);
		}else{
			custProductApply.setRejectMsg(map.get("message"));
			custProductApply.setSuggestion("");
			custProductApply.setCreditAmt(0);
			custProductApply.setCreditExpiretime("");
			custProductApply.setAuditResult(5);
		}
		return custProductApply;
	}

	@Override
	public Object getProductCheckCreditParam(Cust cust) {
		CustAccount account=new CustAccount();
		account.setCustId(cust.getCustId());
		List<CustAccount> accountList=custAccountService.find(account);
		Map<String, String> map = new HashMap<>();
		map.put("phone", accountList.get(0).getUserName());
		map.put("name",cust.getCustName());
		map.put("idNum",cust.getCustIdno());
		return map;
	}

	@Override
	public Object checkCreditResult(Long custId, Long productId, Object commitOutput) throws Exception {
		if(commitOutput!=null){
			Map map=(Map)commitOutput;
			if("1".equals(map.get("code"))){
				return map;
			}
		}
		return null;
	}
}
